using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine.UI;

namespace CGF
{
    [CustomEditor(typeof(I18N))]
    public class I18NEditor : Editor
    {
        I18N i18n;
        bool haveChange;

        private void OnEnable()
        {
            i18n = (I18N)target;
        }

        public override void OnInspectorGUI()
        {
            i18n.language = (ELanguage)EditorGUILayout.EnumPopup("语言", i18n.language);

            EditorGUILayout.Space(5);

            for (int i = 0; i < i18n.nodes.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                I18N.Node node = i18n.nodes[i];
                EditorGUILayout.LabelField(i.ToString(), GUILayout.MaxWidth(15));
                EditorGUILayout.ObjectField(node.go, typeof(GameObject), true, GUILayout.MaxWidth(150));
                EditorGUILayout.LabelField("⇒", GUILayout.MaxWidth(15));
                int langIndex = (int)i18n.language;
                if (langIndex >= node.indexLanguages.Count) node.indexLanguages.Add("");
                node.indexLanguages[langIndex] = EditorGUILayout.TextField(node.indexLanguages[langIndex]);
                if (node.text && !node.text.text.Equals(StringHelper.SurportSpace(node.indexLanguages[langIndex])))
                {
                    node.text.text = StringHelper.SurportSpace(node.indexLanguages[langIndex]);
                    RepainCanvas();
                    haveChange = true;
                }
                if (GUILayout.Button("↑", GUILayout.MaxWidth(20)))
                {
                    if (i > 0)
                    {
                        List<I18N.Node> _nodes = new List<I18N.Node>();
                        for (int j = 0; j < i18n.nodes.Count; j++)
                        {
                            if (j == i - 1)
                            {
                                _nodes.Add(i18n.nodes[j + 1]);
                            }
                            else if (j == i)
                            {
                                _nodes.Add(i18n.nodes[j - 1]);
                            }
                            else
                            {
                                _nodes.Add(i18n.nodes[j]);
                            }
                        }
                        i18n.nodes = _nodes;
                        haveChange = true;
                        return;
                    }
                }
                if (GUILayout.Button("X", GUILayout.MaxWidth(25)))
                {
                    i18n.nodes.RemoveAt(i);
                    haveChange = true;
                }
                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("添加", GUILayout.MaxWidth(30));
            i18n.newText = (Text)EditorGUILayout.ObjectField(i18n.newText, typeof(Text), true);
            EditorGUILayout.EndHorizontal();
            if (i18n.newText)
            {
                for (int i = 0; i < i18n.nodes.Count; i++)
                {
                    if (i18n.nodes[i].text == i18n.newText)
                    {
                        EditorUtility.DisplayDialog("提示", $"该节点 “{name}” 已存在", "确定");
                        i18n.newText = null;
                        return;
                    }
                }
                I18N.Node node = new I18N.Node(i18n.newText.gameObject);
                node.indexLanguages[(int)i18n.language] = i18n.newText.text;
                node.text = i18n.newText;
                i18n.nodes.Add(node);
                i18n.newText = null;
                haveChange = true;
            }

            EditorGUILayout.Space(10);

            for (int i = 0; i < i18n.keys.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();

                if (i >= i18n.keys.Count) i18n.keys.Add("");
                string key = i18n.keys[i];
                i18n.keys[i] = EditorGUILayout.TextField(i18n.keys[i], GUILayout.MaxWidth(150));
                if (!key.Equals(i18n.keys[i]))
                {
                    haveChange = true;
                }

                EditorGUILayout.LabelField("⇒", GUILayout.MaxWidth(15));
                if (i >= i18n.keyContents.Count) i18n.keyContents.Add(new I18N.KeyContent());
                int langIndex = (int)i18n.language;
                if (langIndex > i18n.keyContents[i].languages.Count - 1)
                {
                    i18n.keyContents[i].languages.Add("");
                }
                string content = i18n.keyContents[i].languages[langIndex];
                i18n.keyContents[i].languages[langIndex] = EditorGUILayout.TextField(i18n.keyContents[i].languages[langIndex]);
                if (!content.Equals(i18n.keyContents[i].languages[langIndex]))
                {
                    haveChange = true;
                }

                if (GUILayout.Button("↑", GUILayout.MaxWidth(20)))
                {
                    if (i > 0)
                    {
                        List<string> _keys = new List<string>();
                        List<I18N.KeyContent> _contents = new List<I18N.KeyContent>();
                        for (int j = 0; j < i18n.keys.Count; j++)
                        {
                            if (j == i - 1)
                            {
                                _keys.Add(i18n.keys[j + 1]);
                                _contents.Add(i18n.keyContents[j + 1]);
                            }
                            else if (j == i)
                            {
                                _keys.Add(i18n.keys[j - 1]);
                                _contents.Add(i18n.keyContents[j - 1]);
                            }
                            else
                            {
                                _keys.Add(i18n.keys[j]);
                                _contents.Add(i18n.keyContents[j]);
                            }
                        }
                        i18n.keys = _keys;
                        i18n.keyContents = _contents;
                        haveChange = true;
                        return;
                    }
                }
                if (GUILayout.Button("X", GUILayout.MaxWidth(25)))
                {
                    i18n.keys.RemoveAt(i);
                    i18n.keyContents.RemoveAt(i);
                    haveChange = true;
                }

                EditorGUILayout.EndHorizontal();
            }

            if (GUILayout.Button("添加自定义字段"))
            {
                i18n.keys.Add("");
                i18n.keyContents.Add(new I18N.KeyContent());
                haveChange = true;
            }

            if (GUILayout.Button("应用"))
            {
                SavePrefabI18NToJson();
            }

            if (haveChange)
            {
                haveChange = false;
                EditorUtility.SetDirty(target);
            }
        }

        private void RepainCanvas()
        {
            Canvas canvas = i18n.GetComponentInParent<Canvas>();
            if (canvas)
            {
                canvas.enabled = false;
                canvas.enabled = true;
            }
        }

        [MenuItem("CGFramework/生成多语言配置资源", priority = -950)]
        public static void SavePrefabI18NToJson()
        {
            I18NConfig config = new I18NConfig();
            string[] allPrefabPaths = Directory.GetFiles($"{Application.dataPath}/{Define.BundleFolder}", "*.prefab", SearchOption.AllDirectories);
            for (int i = 0; i < allPrefabPaths.Length; i++)
            {
                string prefabPath = allPrefabPaths[i].Replace("\\", "/").Replace(Application.dataPath, "Assets");
                GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
                I18N map = prefab.GetComponent<I18N>();
                if (map && (map.nodes.Count > 0 || map.keys.Count > 0))
                {
                    prefabPath = prefabPath.Replace("Assets/", "").Replace(".prefab", "");
                    I18NConfig.PrefabConfig prefabConfig = new I18NConfig.PrefabConfig();
                    string prefabName = prefabPath.Substring(prefabPath.LastIndexOf('/') + 1);
                    config.prefabConfigs.Add(prefabName, prefabConfig);
                    prefabConfig.indexContents = new List<List<string>>();
                    prefabConfig.keys = new List<string>();
                    prefabConfig.keyContents = new List<List<string>>();
                    foreach (var node in map.nodes)
                    {
                        List<string> language = new List<string>();
                        for (int k = 0; k < node.indexLanguages.Count; k++)
                        {
                            language.Add(node.indexLanguages[k]);
                        }
                        prefabConfig.indexContents.Add(language);
                    }
                    for (int j = 0; j < map.keys.Count; j++)
                    {
                        prefabConfig.keys.Add(map.keys[j]);
                        prefabConfig.keyContents.Add(map.keyContents[j].languages);
                    }
                }
            }
            string saveFolder = CGFConfig.Instance.ResStrategy == EResStrategy.Resources ? "Resources" : Define.ConfigFolder;
            string savePath = $"{saveFolder}/{Define.I18NAbName}.txt";
            if (!Directory.Exists($"{Application.dataPath}/{saveFolder}"))
            {
                Directory.CreateDirectory($"{Application.dataPath}/{saveFolder}");
                AssetDatabase.ImportAsset($"Assets/{saveFolder}");
            }
            File.WriteAllText($"{Application.dataPath}/{savePath}", DecodeUnicodeString(config.ToJson()), Encoding.UTF8);
            AssetDatabase.ImportAsset($"Assets/{savePath}");
            Debug.Log($"已保存到:{savePath}");
        }

        //将Unicode转回中文，直接中文存储
        private static string DecodeUnicodeString(string unicodeString)
        {
            return System.Text.RegularExpressions.Regex.Replace(unicodeString, @"\\u([0-9A-Fa-f]{4})", match => ((char)int.Parse(match.Groups[1].Value,
                    System.Globalization.NumberStyles.HexNumber)).ToString()
            );
        }
    }
}
